home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / unix / shel301a.2 < prev    next >
Text File  |  1988-12-06  |  55KB  |  2,203 lines

  1. Path: xanth!ames!ncar!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i088:  shell - csh-like shell v3.01a, Part02/03
  5. Message-ID: <10489@swan.ulowell.edu>
  6. Date: 5 Dec 88 22:32:58 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2192
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: PERUGIA@ICNUCEVM.BITNET (Cesare Dieni)
  12. Posting-number: Volume 2, Issue 88
  13. Archive-name: unix/shell301a.2
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    globals.c
  23. #    main.c
  24. #    makefile
  25. #    rawconsole.c
  26. #    run.c
  27. #    set.c
  28. #    shell.h
  29. #    shellfunctions.h
  30. #    sub.c
  31. # This archive created: Mon Dec  5 17:25:21 1988
  32. cat << \SHAR_EOF > globals.c
  33.  
  34. /*
  35.  * GLOBALS.C
  36.  *
  37.  * (c)1986 Matthew Dillon     9 October 1986
  38.  *
  39.  * Version 2.07M by Steve Drew 10-Sep-87
  40.  *
  41.  *    Most global variables.
  42.  *
  43.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  44.  *
  45.  */
  46.  
  47. char *v_titlebar="_titlebar";    /* Window title                */
  48. char *v_prompt    ="_prompt";    /* your prompt (ascii command)        */
  49. char *v_hist    ="_history";    /* set history depth (value)        */
  50. char *v_histnum    ="_histnum";    /* set history numbering var        */
  51. char *v_debug    ="_debug";    /* set debug mode            */
  52. char *v_verbose    ="_verbose";    /* set verbose for source files        */
  53. char *v_stat    ="_maxerr";    /* worst return value to date        */
  54. char *v_lasterr    ="_lasterr";    /* return value from last comm.        */
  55. char *v_cwd    ="_cwd";    /* current directory            */
  56. char *v_except    ="_except";    /* "nnn;command"            */
  57. char *v_passed    ="_passed";    /* passed arguments to source file    */
  58. char *v_path    ="_path";    /* search path for external commands    */
  59. char *v_gotofwd    ="_gtf";    /* set name for fwd goto name        */
  60.  
  61. struct HIST *H_head, *H_tail;    /* HISTORY lists */
  62.  
  63. struct PERROR Perror[]= {    /* error code->string */
  64.     103,    "Insufficient free storage",
  65.     105,    "Task table full",
  66.     120,    "Argument line invalid or too long",
  67.     121,    "File is not an object module",
  68.     122,    "Invalid resident library during load",
  69.     201,    "No default directory",
  70.     202,    "Object in use",
  71.     203,    "Object already exists",
  72.     204,    "Directory not found",
  73.     205,    "Object not found",
  74.     206,    "Bad stream name",
  75.     207,    "Object too large",
  76.     209,    "Action not known",
  77.     210,    "Invalid stream component name",
  78.     211,    "Invalid object lock",
  79.     212,    "Object not of required type",
  80.     213,    "Disk not validated",
  81.     214,    "Disk write protected",
  82.     215,    "Rename across devices",
  83.     216,    "Directory not empty",
  84.     217,    "Too many levels",
  85.     218,    "Device not mounted",
  86.     219,    "Seek error",
  87.     220,    "Comment too long",
  88.     221,    "Disk full",
  89.     222,    "File delete protected",
  90.     223,    "File write protected",
  91.     224,    "File read protected",
  92.     225,    "Not a DOS disk",
  93.     226,    "No disk",
  94.  
  95.  /* custom error messages */
  96.  
  97.     500,    "Bad arguments",
  98.     501,    "Label not found",
  99.     502,    "Must be within source file",
  100.     503,    "Syntax Error",
  101.     504,    "Redirection error",
  102.     505,    "Pipe error",
  103.     506,    "Too many arguments",
  104.     507,    "Destination not a directory",
  105.     508,    "Cannot mv a filesystem",
  106.     509,    "Error in command name",
  107.     510,    "Bad drive name",
  108.     511,    "Illegal number",
  109.     0,    NULL
  110. };
  111.  
  112. char *av[MAXAV];        /* Internal argument list        */
  113. long Src_base[MAXSRC];        /* file pointers for source files    */
  114. long Src_pos[MAXSRC];        /* seek position storage for same    */
  115. char If_base[MAXIF];        /* If/Else stack for conditionals    */
  116. int H_len, H_tail_base;        /* History associated stuff        */
  117. int H_stack;            /* AddHistory disable stack        */
  118. int E_stack;            /* Exception disable stack        */
  119. int Src_stack, If_stack;    /* Stack Indexes            */
  120. int forward_goto;        /* Flag for searching for foward lables    */
  121. int ac;                /* Internal argc            */
  122. int debug;            /* Debug mode                */
  123. int disable;            /* Disable com. execution (conditionals)*/
  124. int Verbose;            /* Verbose mode for source files    */
  125. int Lastresult;            /* Last return code            */
  126. int Exec_abortline;        /* flag to abort rest of line        */
  127. int Quit;            /* Quit flag                */
  128. long Cout, Cin;            /* Current input and output file handles*/
  129. long Cout_append;        /* append flag for Cout            */
  130. char *Cin_name, *Cout_name;    /* redirection input/output name or NULL*/
  131. char *Pipe1, *Pipe2;        /* the two pipe temp. files        */
  132. struct Process *Myprocess;
  133. struct CommandLineInterface *Mycli;
  134. int S_histlen = 20;        /* Max # history entries        */
  135. unsigned int options;
  136. SHAR_EOF
  137. cat << \SHAR_EOF > main.c
  138. /*
  139.  * MAIN.C
  140.  *
  141.  * Matthew Dillon, 24 Feb 1986
  142.  * (c)1986 Matthew Dillon     9 October 1986
  143.  *
  144.  * Version 2.07M by Steve Drew 10-Sep-87
  145.  *
  146.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  147.  *
  148.  */
  149.  
  150. char *shellctr="CshCounter";
  151.  
  152. extern char *v_titlebar, *v_prompt, *v_hist, *v_lasterr, *v_path;
  153.  
  154. int aux; /* for use with aux: driver */
  155. char *oldtitle;
  156. char trueprompt[100];
  157. char Inline[260];
  158. struct IntuitionBase *IntuitionBase;
  159. struct Window *w;
  160. struct ArpBase *ArpBase;
  161.  
  162. main(argc, argv)
  163. register char *argv[];
  164. {
  165. #if RAW_CONSOLE
  166.     char *rawgets();
  167. #endif
  168.  
  169. register unsigned int i;
  170. extern int Enable_Abort;
  171. char buf[10];
  172.  
  173. ArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L);
  174. if (ArpBase==NULL) { printf("No arp library\n"); exit(0); }
  175.  
  176. Forbid();
  177. i=Errno=0;
  178. if (Getenv(shellctr,buf,10L)) {
  179.     i=(int)(long)Atol(buf);
  180.     if (Errno) i=0;
  181.     }
  182. sprintf(buf,"%d",i+1);
  183. Setenv(shellctr,buf);
  184. Permit();
  185.  
  186. IntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase;
  187. w=IntuitionBase->ActiveWindow;
  188. oldtitle=(char *)(w->Title);
  189.  
  190. set_var(LEVEL_SET, v_titlebar, "CShell V3.01A");
  191. set_var(LEVEL_SET, v_prompt,
  192.     (IsInteractive(Input())) ? "\23337m%p> \2330m" : "");
  193. set_var(LEVEL_SET, v_hist, "20");
  194. set_var(LEVEL_SET, v_lasterr, "0");
  195. set_var(LEVEL_SET, v_path, "RAM:,RAM:c/,df0:c/,df1:c/,sys:system/");
  196. set_var(LEVEL_SET, "_insert", "1");
  197. set_var(LEVEL_SET, "f1", "cdir df0:\15");
  198. set_var(LEVEL_SET, "F1", "cdir df1:\15");
  199. set_var(LEVEL_SET, "f3", "cdir RAM:\15");
  200. set_var(LEVEL_SET, "F3", "cdir vd0:\15");
  201. set_var(LEVEL_SET, "f4", "cd df0:\15");
  202. set_var(LEVEL_SET, "F4", "cd df1:\15");
  203. set_var(LEVEL_SET, "f5", "cls; ls\15");
  204. set_var(LEVEL_SET, "F5", "cdir ");
  205. set_var(LEVEL_SET, "f6", "lc\15");
  206. set_var(LEVEL_SET, "f7", "info\15");
  207. set_var(LEVEL_SET, "F7", "assign \15");
  208. set_var(LEVEL_SET, "f8", "window -lf\15");
  209. set_var(LEVEL_SET, "F8", "window -sb\15");
  210. set_var(LEVEL_SET, "f10", "cls\15");
  211. set_var(LEVEL_SET, "F10", "exit\15");
  212. set_var(LEVEL_ALIAS, "cls", "echo -n ^l");
  213. set_var(LEVEL_ALIAS, "lc", "ls -s");
  214. set_var(LEVEL_ALIAS, "kr", "rm -r RAM:* >NIL:");
  215. set_var(LEVEL_ALIAS, "cdir", "%q cd $q; cls; dir");
  216. set_var(LEVEL_ALIAS, "exit", "endcli;quit");
  217. set_var(LEVEL_ALIAS, "lp", "cat >PRT:");
  218. init();
  219. seterr();
  220. do_pwd(NULL); /* set $_cwd */
  221. Enable_Abort = 0;
  222. for (i = 1; i < argc; ++i) {
  223.     if (!strcmp(argv[i],"-c")) {
  224.         Inline[0] = ' ';
  225.         Inline[1] = '\0';
  226.         while (++i < argc)
  227.             { strcat(Inline,argv[i]); strcat(Inline," "); }
  228.         exec_command(Inline);
  229.         main_exit(Lastresult);
  230.         }
  231.     if (!strcmp(argv[i],"-a")) { aux = 1; continue; }
  232.     sprintf (Inline, "source %s",argv[i]);
  233.     av[1] = argv[i];
  234.     do_source (Inline);
  235.     }
  236. for (;;) {
  237.    if (breakcheck())
  238.     while (WaitForChar(Input(), 100L) || stdin->_bp < stdin->_bend)
  239.         gets(Inline);
  240.    clearerr(stdin);  /* prevent acidental quit */
  241. #if RAW_CONSOLE
  242.    if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0);
  243. #else
  244.    printf("%s", disable ? "_ " : trueprompt);
  245.    fflush(stdout);
  246.    if (Quit || !gets(Inline)) main_exit(0);
  247. #endif
  248.    breakreset();
  249.    if (*Inline) exec_command(Inline);
  250.    }
  251. }
  252.  
  253. main_exit(n)
  254. {
  255. register unsigned short i;
  256. char buf[10];
  257.  
  258. Getenv(shellctr,buf,10L);
  259. i=(int)Atol(buf);
  260. sprintf(buf,"%d",i-1);
  261. Setenv(shellctr,buf);
  262. SetWindowTitles(w,oldtitle,-1L);
  263. for (i=1; i<MAXMYFILES; i++) myclose(i);
  264. ArpExit(0L,0L);            /* Intuition need not to be closed */
  265. }
  266.  
  267. init()
  268. {
  269. static char pipe1[32], pipe2[32];
  270.  
  271. stdin->_flags    |= 0x80;    /* make sure we're set as a tty */
  272. stdout->_flags    |= 0x80;    /* in case of redirection in .login */
  273. #if RAW_CONSOLE
  274.     printf("\23312{");    /* enable window resize reports */
  275. #endif
  276. Close(_devtab[2].fd);
  277. _devtab[2].mode |= O_STDIO;
  278. _devtab[2].fd = _devtab[1].fd;    /* set stderr to Output() otherwise */
  279.         /* don't work with aux driver */
  280. Myprocess = (struct Process *)FindTask(0L);
  281. Mycli=(struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2);
  282. Pipe1 = pipe1;
  283. Pipe2 = pipe2;
  284. sprintf(pipe1, "ram:pipe1_%ld", Myprocess);
  285. sprintf(pipe2, "ram:pipe2_%ld", Myprocess);
  286. }
  287.  
  288. breakcheck()
  289. {
  290. return (int)(SetSignal(0L,0L) & SIGBREAKF_CTRL_C);
  291. }
  292.  
  293. breakreset()
  294. {
  295. SetSignal(0L, SIGBREAKF_CTRL_C);
  296. }
  297.  
  298. dobreak()
  299. {
  300. if (breakcheck()) { printf("^C\n"); return(1); }
  301. return(0);
  302. }
  303.  
  304. /* this routine causes manx to use this Chk_Abort() rather than it's own */
  305. /* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
  306. /* is zero).  Since we want to check for our own ^C's             */
  307.  
  308. Chk_Abort()
  309. {
  310. return(0);
  311. }
  312.  
  313. _wb_parse()
  314. {
  315. }
  316.  
  317. do_howmany()
  318. {
  319. char buf[10];
  320.  
  321. Getenv(shellctr, buf, 10L);
  322. printf("Shell(s) running: %s\n",buf);
  323. }
  324. SHAR_EOF
  325. cat << \SHAR_EOF > makefile
  326. ######################################################################
  327. #
  328. # Makefile to build Shell 3.01A
  329. # by Carlo Borreo & Cesare Dieni 17-Nov-88
  330. #
  331. ######################################################################
  332.  
  333. OBJS    = run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o \
  334.       globals.o rawconsole.o
  335.  
  336. INCL    = shell.h
  337.  
  338. Shell   : Shell.syms $(OBJS)
  339.     ln  +q -m -o Shell $(OBJS) -la -lc
  340.  
  341. Shell.syms : $(INCL)
  342.     cc +HShell.syms shell.h
  343.  
  344. rawconsole.o : rawconsole.c $(INCL)
  345.     cc +IShell.syms rawconsole.c
  346.  
  347. run.o   : run.c $(INCL)
  348.     cc +IShell.syms run.c
  349.  
  350. main.o  : main.c $(INCL)
  351.     cc +IShell.syms main.c
  352.  
  353. comm1.o : comm1.c $(INCL)
  354.     cc +IShell.syms comm1.c
  355.  
  356. comm2.o : comm2.c $(INCL)
  357.     cc +IShell.syms comm2.c
  358.  
  359. comm3.o : comm3.c $(INCL)
  360.     cc +IShell.syms comm3.c
  361.  
  362. set.o   : set.c $(INCL)
  363.     cc +IShell.syms set.c
  364.  
  365. sub.o   : sub.c $(INCL)
  366.     cc +IShell.syms sub.c
  367.  
  368. globals.o : globals.c $(INCL)
  369.     cc +IShell.syms globals.c
  370.  
  371. execom.o : execom.c $(INCL)
  372.     cc +IShell.syms execom.c
  373. SHAR_EOF
  374. cat << \SHAR_EOF > rawconsole.c
  375. /*
  376.  * RawConsole.c
  377.  *
  378.  * Shell 2.07M  17-Jun-87
  379.  * console handling, command line editing support for Shell
  380.  * using new console packets from 1.2.
  381.  * Written by Steve Drew. (c) 14-Oct-86.
  382.  * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
  383.  *
  384.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  385.  *
  386.  */
  387.  
  388. #if RAW_CONSOLE
  389. extern int aux; /* for use with aux: */
  390.  
  391. #define SETRAW setrawcon(-1L);
  392. #define SETCON setrawcon(0L);
  393.  
  394. char *rawgets(line,prompt)
  395. char *line, *prompt;
  396. {
  397. char *get_var();
  398. char *gets();
  399. register int n, pl;
  400. register int max, i;
  401. unsigned char c1,c2,c3;
  402. char fkeys[5];
  403. char *s, *tyahdptr;
  404. char *ps;
  405. int fkey, savn;
  406. int insert = 1;
  407. char rep[20];
  408. char typeahd[256];
  409. static int width;
  410. int recall = -1;
  411. struct HIST *hist;
  412.  
  413. if (aux) {
  414.     printf("%s",prompt);
  415.     fflush(stdout);
  416.     }
  417. if (!IsInteractive(Input()) || aux ) return(gets(line));
  418. if (WaitForChar((long)Input(), 100L) ||   /* don't switch to 1L ...*/
  419.         stdin->_bp < stdin->_bend) {     /* else causes read err's*/
  420.     gets(line);
  421.     return(line);
  422.     }
  423. SETRAW;
  424. printf("\015%s\2336n",prompt);
  425. savn = pl = n = 0;
  426. tyahdptr = typeahd;
  427. while((typeahd[n]=getchar()) != 'R') {
  428.     if ((unsigned char)typeahd[n] == 155) savn = n;
  429.     n++;
  430.     }
  431.  
  432.     /* typeahd now contains possible type a head chars
  433.        followed by <CSI> cursor position report.
  434.     */
  435. typeahd[savn]  = '\0';
  436. if (typeahd[n-2] != ';') pl = (typeahd[n-2] - 48) * 10;
  437. pl += typeahd[n-1] - 49;
  438. ps = line + pl;
  439. line[max = i = pl] = '\0';
  440.  
  441. if (!width) width = 77;
  442. if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
  443.  
  444. while( (c1 = *tyahdptr) != '\0' || (c1 = getchar()) != 255) {
  445.         if (*tyahdptr) ++tyahdptr;
  446.         switch(c1) {
  447.             case 155:
  448.                  c2 = getchar();
  449.                  switch(c2) {
  450.                      case 'A':                  /* up arrow   */
  451.                         n = ++recall;
  452.                      case 'B':                  /* down arrow */
  453.                         line[pl] = '\0';
  454.                         if (recall >= 0 || c2 == 'A') {
  455.                             if (c2 == 'B') n = --recall;
  456.                             if (recall >= 0) {
  457.                                 for(hist = H_head; hist && n--;
  458.                                     hist = hist->next);
  459.                                 if (hist) strcpy(&line[pl],hist->line);
  460.                                 else recall = H_len;
  461.                             }
  462.                         }
  463.                         if (i != pl)
  464.                             printf("\233%dD",i);
  465.                         printf("\015\233J%s%s",prompt,ps);
  466.                         i = max = strlen(ps) + pl;
  467.                         break;
  468.                      case 'C':                  /* right arrow*/
  469.                         if (i < max) {
  470.                             i++;
  471.                             printf("\233C");
  472.                         }
  473.                         break;
  474.                      case 'D':                  /* left arrow */
  475.                         if (i > pl) {
  476.                             i--;
  477.                             printf("\233D");
  478.                         }
  479.                         break;
  480.                      case 'T':           /* shift-up   */
  481.                        n = recall = H_len-1;
  482.                      case 'S':           /* shift-down */
  483.                        line[pl] = '\0';
  484.                        if (c2 == 'S') {
  485.                            n = recall = 0;
  486.                            if (H_head) strcpy(&line[pl], H_head->line);
  487.                        }
  488.                        else if (H_tail) strcpy(&line[pl], H_tail->line);
  489.                        printf("\015\233J%s%s",prompt,ps);
  490.                        i = max = strlen(ps) + pl;
  491.                        break;
  492.                     case ' ':                   /* shift -> <-*/
  493.                         c3 = getchar();
  494.                                      switch(c3) {
  495.                     case('@'):      /* shift ->   */
  496.                         while (ps[i-strlen(prompt)] == ' ' && i<max) {
  497.                             i++;
  498.                             printf("\233C");
  499.                         }
  500.                         while (ps[i-strlen(prompt)] != ' ' && i<max) {
  501.                             i++;
  502.                             printf("\233C");
  503.                         }
  504.                         break;
  505.                     case('A'):      /* shift <-   */
  506.                         while (ps[i-strlen(prompt)-1] == ' ' && i>pl) {
  507.                             i--;
  508.                             printf("\233D");
  509.                         }
  510.                         while (ps[i-strlen(prompt)-1] != ' ' && i>pl) {
  511.                             i--;
  512.                             printf("\233D");
  513.                         }
  514.                         break;
  515.                         default:
  516.                         break;
  517.                     }
  518.                         break;
  519.                     default:
  520.                         c3 = getchar();
  521.                         if (c3 == '~') {
  522.                             fkey = c2;
  523.                             fkeys[0] = 'f';
  524.                             if (c2 == 63) {
  525.                                 strcpy(ps,"help");
  526.                                 goto done;
  527.                             }
  528.                         }
  529.                         else if (getchar() != '~') { /* window was resized */
  530.                             while(getchar() != '|');
  531.                             printf("\2330 q"); /* get window bounds */
  532.                             n = 0;
  533.                             while((rep[n] = getchar()) != 'r' && n++ < 20);
  534.                             width = (rep[n-3] - 48) * 10 + rep[n-2] - 48;
  535.                             rep[n-1] = '\0';
  536.                             set_var (LEVEL_SET, "_width", &rep[n-3]);
  537.                             break;
  538.                         }
  539.                         else {
  540.                             fkey = c3;
  541.                             fkeys[0] = 'F';
  542.                         }
  543.                         sprintf(fkeys+1,"%d",fkey - 47);
  544.                         if (!(s = get_var(LEVEL_SET, fkeys))) break;
  545.                         tyahdptr = strcpy(typeahd,s);
  546.                         break;
  547.                     }
  548.                 break;
  549.             case 8:
  550.                 if (i > pl) {
  551.                     i--;
  552.                     printf("\010");
  553.                 }
  554.                 else break;
  555.             case 127:
  556.                 if (i < max) {
  557.                     int j,t,l = 0;
  558.                     movmem(&line[i+1],&line[i],max-i);
  559.                     --max;
  560.                     printf("\233P");
  561.                     j = width - i % width - 1;   /* amount to end     */
  562.                     t = max/width - i/width;     /* no of lines       */
  563.                     for(n = 0; n < t; n++) {
  564.                         l += j;                  /* no. of char moved */
  565.                         if (j) printf("\233%dC",j); /* goto eol       */
  566.                         printf("%c\233P",line[width*(i/width+n+1)-1]);
  567.                         j = width-1;
  568.                     }
  569.                     if (t)
  570.                     printf("\233%dD",l+t);   /* get back */
  571.                 }
  572.                 break;
  573.             case 18:
  574.                 n = i/width;
  575.                 if (n) printf("\233%dF",n);
  576.                 printf("\015\233J%s%s",prompt,ps);
  577.                 i = max;
  578.                 break;
  579.             case 27:
  580.                 break;
  581.             case 1:
  582.                 insert ^= 1;
  583.                 break;
  584.             case 21:
  585.             case 24:
  586.             case 26:
  587.                 if (i > pl)
  588.                     printf("\233%dD",i-pl);
  589.                 i = pl;
  590.                 if (c1 == 26) break;
  591.                 printf("\233J");
  592.                 max = i;
  593.                 line[i] = '\0';
  594.                 break;
  595.             case 11:        /* ^K */
  596.                 printf("\233J");
  597.                 max = i;
  598.                 line[i] = '\0';
  599.                 break;
  600.             case 28:        /* ^\ */
  601.                 SETCON;
  602.                 return(NULL);
  603.             case 5:
  604.                 printf("\233%dC",max - i);
  605.                 i = max;
  606.                 break;
  607.             case 10:
  608.             case 13:
  609.                 line[max] = '\0';
  610. done:           printf("\233%dC\n",max - i);
  611.  
  612.                 SETCON;
  613.                 strcpy(line, ps);
  614.                 return(line);
  615.             default:
  616.                 c1 &= 0x7f;
  617.                 if (c1 == 9) c1 = 32;
  618.                 if (c1 > 31 & i < 256) {
  619.                     if (i < max && insert) {
  620.                         int j,t,l = 0;
  621.                         movmem(&line[i], &line[i+1], max - i);
  622.                         printf("\233@%c",c1);
  623.                         t = max/width - i/width;
  624.                         j = width - i % width - 1;
  625.                         for(n = 0; n < t; n++) {
  626.                             l += j;
  627.                             if (j) printf("\233%dC",j);
  628.                             printf("\233@%c",line[width*(i/width+n+1)]);
  629.                             j = width-1;
  630.                         }
  631.                         if (t) printf("\233%dD",l + t);
  632.                         ++max;
  633.                     }
  634.                     else {
  635.                         if(i == pl && max == i) printf("\015%s%s",prompt,ps);
  636.                         putchar(c1);
  637.                     }
  638.                     line[i++] = c1;
  639.                     if (max < i) max = i;
  640.                     line[max] = '\0';
  641.                 }
  642.         }
  643.     }
  644. SETCON;
  645. return(NULL);
  646. }
  647.  
  648. setrawcon(flag) /* -1L=RAW:, 0L=CON: */
  649. long flag;
  650. {
  651. long packargs[8];
  652.  
  653. packargs[0]=flag;
  654. SendPacket(994L, packargs, Myprocess->pr_ConsoleTask);
  655. }
  656.  
  657. #endif
  658. SHAR_EOF
  659. cat << \SHAR_EOF > run.c
  660.  
  661. /*
  662.  * RUN.C
  663.  *
  664.  * (c)1986 Matthew Dillon     9 October 1986
  665.  *
  666.  *    RUN   handles running of external commands.
  667.  *
  668.  * Version 2.07M by Steve Drew 10-Sep-87
  669.  *
  670.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  671.  *
  672.  */
  673.  
  674. extern char *v_path;
  675. char *FindIt();
  676.  
  677. do_run(str)
  678. char *str;
  679. {
  680. int i, len, retcode;
  681. char buf[200]; /* enough space for 100 char cmd name + path stuff */
  682. char *path;
  683.  
  684. char *p = av[0];
  685. char **args = av+1;
  686.  
  687. while(*p++) *p &= 0x7F;      /* allow "com mand" */
  688.  
  689. while(*args) {                /* if any arg contains a space then */
  690.     if (index(*args,' ')) {        /* surround with quotes, since must */
  691.     i = strlen(*args);        /* of specified via "arg u ment" on */
  692.     movmem(*args,(*args)+1,i);    /* original command line.        */
  693.     args[0][0] = args[0][i+1] = '\"';    /* mpush in execom.c has    */
  694.     args[0][i+2] = '\0';        /* allowed for these 2 extra bytes. */
  695.     }
  696.     ++args;
  697.     }
  698. if ((len = strlen(av[0])) > 100) { ierror(NULL,509); return -1; }
  699. if (path = FindIt(av[0],"",buf)) retcode = myfexecv(path, av);
  700. else {
  701.     Myprocess->pr_WindowPtr = (APTR)(-1);
  702.     /*
  703.      * manx's fexecv code only allows us 38
  704.      * chars for command name.
  705.      */
  706.     if (len > 37) av[0][37] = '\0';
  707.     retcode = myfexecv(av[0], av);
  708.     Myprocess->pr_WindowPtr = NULL;
  709.     }
  710. if (retcode < 0) {
  711.     char *copy;
  712.     if ((path = FindIt(av[0],".sh",buf)) == NULL) {
  713.         fprintf(stderr,"Command Not Found %s\n",av[0]);
  714.         return -1;
  715.         }
  716.     av[1] = buf;               /* particular to do_source() */
  717.     copy = malloc(strlen(str)+3);
  718.     sprintf(copy,"x %s",str);
  719.     retcode = do_source(copy);
  720.     free(copy);
  721.     }
  722. return retcode;
  723. }
  724.  
  725. char *dofind(cmd, ext, buf)
  726. char *cmd, *ext, *buf;
  727. {
  728. char *ptr, *s;
  729.  
  730. sprintf(buf,"%s%s",cmd,ext);
  731. if (exists(buf)) return buf;
  732. if (BaseName(buf)==buf) {
  733.     s = get_var(LEVEL_SET, v_path);
  734.     while (*s) {
  735.         for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++;
  736.         sprintf(ptr, "%s%s", cmd, ext);
  737.         if (exists(buf)) return buf;
  738.         if (*s) s++;
  739.         }
  740.     }
  741. return NULL;
  742. }
  743.  
  744. char *FindIt(cmd,ext,buf)
  745. char *cmd, *ext, *buf;
  746. {
  747. char *response;
  748.  
  749. Myprocess->pr_WindowPtr = (APTR)(-1);
  750. response=dofind(cmd,ext,buf);
  751. Myprocess->pr_WindowPtr = NULL;
  752. return response;
  753. }
  754.  
  755. myfexecv(cmd, argv)
  756. char *cmd, **argv;
  757. {
  758. long ret_val;
  759. struct FileHandle *fhp;
  760. APTR sav_ret;
  761. register char **ap, *cp, *arg;
  762. int i;
  763. long len, seg, sav, stksiz;
  764. char buf[40];
  765. union {
  766.     long *lp;
  767.     long ll;
  768.     } l, stk;
  769. long oldcin, oldcout;
  770. long doexec();
  771. extern long _savsp;
  772.  
  773. if (seg = LoadPrg(cmd)) goto found;
  774. l.lp = (long *) Mycli->cli_CommandDir;
  775. while (l.ll) {
  776.     l.ll <<= 2;
  777.     sav = CurrentDir(l.lp[1]);
  778.     seg = LoadPrg(cmd);
  779.     CurrentDir(sav);
  780.     if (seg) goto found;
  781.     l.ll = *l.lp;
  782.     }
  783. sprintf(buf, "c:%s", cmd);
  784. if (seg = LoadPrg(buf)) goto found;
  785. return -1;
  786.  
  787. found:
  788.  
  789. stksiz = 4 * Mycli->cli_DefaultStack;
  790. if ((stk.lp = AllocMem(stksiz+8, 0L)) == 0) {
  791.     UnLoadPrg(seg);
  792.     return -1;
  793.     }
  794. for (len=0,ap=argv+1;*ap;ap++)
  795.     len += strlen(*ap) + 1;
  796. if (len==0) len++;
  797. if ((cp = arg = AllocMem(len, 0L)) == 0) {
  798.     UnLoadPrg(seg);
  799.     FreeMem(stk.lp, stksiz+8);
  800.     return -1;
  801.     }
  802. *stk.lp = stksiz + 8;
  803. stk.ll += stksiz;
  804. stk.lp[0] = stksiz;
  805. stk.lp[1] = ((long *)_savsp)[2];
  806. sav_ret = Myprocess->pr_ReturnAddr;
  807. Myprocess->pr_ReturnAddr = (APTR) stk.lp;
  808.  
  809. sav = Mycli->cli_Module;
  810. Mycli->cli_Module = seg;
  811.  
  812. for (ap=argv+1;*ap;ap++) {
  813.     strcpy(cp, *ap);
  814.     if (ap[1]) strcat(cp, " ");
  815.     cp += strlen(cp);
  816.     }
  817. if (len==1) arg[1]='\0';
  818. arg[len-1] = '\n';
  819.  
  820. cp = (char *)((long)Mycli->cli_CommandName << 2);
  821. movmem(cp, buf, 40);
  822. strcpy(cp+1, cmd);
  823. cp[0] = strlen(cmd);
  824.  
  825. fhp = (struct FileHandle *) (Myprocess->pr_CIS << 2);
  826. strncpy(fhp->fh_Buf<<2, arg, (int)(len < 200?len:199));
  827. fhp->fh_Pos = 0;
  828. fhp->fh_End = len < 200?len:199;
  829. oldcin  = Myprocess->pr_CIS;
  830. oldcout = Myprocess->pr_COS;
  831.  
  832. ret_val = doexec(len, stksiz, stksiz+8, len, arg, (seg+1)<<2, stk.ll);
  833.  
  834. Myprocess->pr_CIS = oldcin;
  835. Myprocess->pr_COS = oldcout;
  836. fhp->fh_Pos = fhp->fh_End;
  837. UnLoadPrg(Mycli->cli_Module);
  838. Myprocess->pr_ReturnAddr = sav_ret;
  839. Mycli->cli_Module = sav;
  840. FreeMem(arg, len);
  841. movmem(buf, cp, 40);
  842. return ret_val;
  843. }
  844.  
  845. static long doexec()
  846. {
  847. #asm
  848.     movem.l    d3-d7/a2-a5,-(sp)        ;save registers
  849.     lea        savsp(pc),a0
  850.     move.l    sp,(a0)                    ;save our sp
  851.     movem.l    8(a5),d0/d2/d3/d4/a0/a4/a7    ;load params
  852.     move.l    4(sp),a3                ;get old sp from CLI
  853.     movem.l    4(a3),a1/a2/a5/a6        ;get BCPL environment
  854.     move.l    d0,12(a1)                ;set length
  855.     move.l    a0,d1                    ;copy to dreg
  856.     lsr.l    #2,d1                    ;convert to BPTR
  857.     move.l    d1,8(a1)                ;set ptr
  858.     move.l    a0,d1                    ;copy to d1 as well
  859.     jsr        (a4)                    ;call new program
  860.     movem.l    (sp)+,d2/d3                ;get stk siz and old sp
  861.     move.l    sp,a1                    ;save current sp
  862.     move.l    savsp(pc),sp            ;get back our sp
  863.     movem.l    (sp)+,d3-d7/a2-a5        ;get back registers
  864.     move.l    d0,-(sp)                ;save return code
  865.     sub.l    d2,a1                    ;back up a bit
  866.     sub.l    #8,a1                    ;back up over header
  867.     move.l    (a1),d0                    ;get size to free
  868.     move.l    4,a6                    ;get ExecBase
  869.     jsr        -210(a6)                ;free the memory
  870.     move.l    (sp)+,d0                ;get the return code
  871. #endasm
  872. }
  873.  
  874. #asm
  875. savsp:
  876.     dc.l    0
  877. #endasm
  878. SHAR_EOF
  879. cat << \SHAR_EOF > set.c
  880.  
  881. /*
  882.  * SET.C
  883.  *
  884.  * (c)1986 Matthew Dillon     9 October 1986
  885.  *
  886.  * Version 2.07M by Steve Drew 10-Sep-87
  887.  *
  888.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  889.  *
  890.  */
  891.  
  892. extern char *v_titlebar, *v_verbose, *v_hist, *v_debug, *v_prompt;
  893. extern struct Window *w;
  894.  
  895. #define MAXLEVELS (3 + MAXSRC)
  896.  
  897. struct MASTER {
  898.     struct MASTER *next;
  899.     struct MASTER *last;
  900.     char *name;
  901.     char *text;
  902. };
  903.  
  904. static struct MASTER *Mbase[MAXLEVELS];
  905.  
  906. char *set_var(level, name, str)
  907. register char *name, *str;
  908. {
  909.    register struct MASTER *base = Mbase[level];
  910.    register struct MASTER *last;
  911.    register int len;
  912.  
  913.    for (len = 0; isalphanum(name[len]); ++len);
  914.    while (base != NULL) {
  915.       if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
  916.          Free (base->text);
  917.          goto gotit;
  918.       }
  919.       last = base;
  920.       base = base->next;
  921.    }
  922.    if (base == Mbase[level]) {
  923.       base = Mbase[level] = (struct MASTER *)malloc (sizeof(struct MASTER));
  924.       base->last = NULL;
  925.    } else {
  926.       base = (struct MASTER *)malloc (sizeof(struct MASTER));
  927.       base->last = last;
  928.       last->next = base;
  929.    }
  930.    base->name = malloc (len + 1);
  931.    bmov (name, base->name, len);
  932.    base->name[len] = 0;
  933.    base->next = NULL;
  934. gotit:
  935.    base->text = malloc (strlen(str) + 1);
  936.    strcpy (base->text, str);
  937.    if (*name=='_') sys_vars();
  938.    return (base->text);
  939. }
  940.  
  941. char *get_var (level, name)
  942. register char *name;
  943. {
  944.    register struct MASTER *base = Mbase[level];
  945.    register unsigned char *scr;
  946.    register int len;
  947.  
  948.    for (scr = (unsigned char *)name; *scr && *scr != 0x80 && *scr != ' ' && *scr != ';' && *scr != '|'; ++scr);
  949.    len = scr - name;
  950.  
  951.    while (base != NULL) {
  952.       if (strlen(base->name) == len && strncmp (name, base->name, len) == 0)
  953.          return (base->text);
  954.       base = base->next;
  955.    }
  956.    return (NULL);
  957. }
  958.  
  959. unset_level(level)
  960. {
  961.    register struct MASTER *base = Mbase[level];
  962.  
  963.    while (base) {
  964.       Free (base->name);
  965.       Free (base->text);
  966.       Free (base);
  967.       base = base->next;
  968.    }
  969.    Mbase[level] = NULL;
  970. }
  971.  
  972. unset_var(level, name)
  973. char *name;
  974. {
  975.    register struct MASTER *base = Mbase[level];
  976.    register struct MASTER *last = NULL;
  977.    register int len;
  978.  
  979.    for (len = 0; isalphanum(name[len]); ++len);
  980.    while (base) {
  981.       if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
  982.          if (base != Mbase[level])
  983.             last->next = base->next;
  984.          else
  985.             Mbase[level] = base->next;
  986.          if (base->next != NULL)
  987.             base->next->last = last;
  988.          if (base == Mbase[level])
  989.             Mbase[level] = base->next;
  990.          Free (base->name);
  991.          Free (base->text);
  992.          Free (base);
  993.          return (1);
  994.       }
  995.       last = base;
  996.       base = base->next;
  997.    }
  998.    return (-1);
  999. }
  1000.  
  1001. do_unset_var(str, level)
  1002. char *str;
  1003. {
  1004. register unsigned int i;
  1005.  
  1006. for (i = 1; i < ac; ++i) unset_var (level, av[i]);
  1007. sys_vars();
  1008. return 0;
  1009. }
  1010.  
  1011. do_set_var(command, level)
  1012. char *command;
  1013. {
  1014. register struct MASTER *base = Mbase[level];
  1015. register char *str;
  1016.  
  1017. switch (ac) {
  1018. case 1:
  1019.     while (base && !dobreak()) {
  1020.         printf ("%-10s %s\n", base->name, base->text);
  1021.         base = base->next;
  1022.         }
  1023.     break;
  1024. case 2:
  1025.     if (str=get_var(level,av[1])) printf ("%-10s %s\n", av[1], str);
  1026.     break;
  1027. default:
  1028.     set_var (level, av[1], next_word (next_word (command)));
  1029.     if (*av[1]=='_') sys_vars();
  1030.     break;
  1031.     }
  1032. return 0;
  1033. }
  1034.  
  1035. extern char trueprompt[100];
  1036.  
  1037. sys_vars()
  1038. {
  1039. register char *str, *t;
  1040.  
  1041. if (strcmp(w->Title, str=get_var(LEVEL_SET, v_titlebar)))
  1042.     SetWindowTitles(w, str, -1L);
  1043. S_histlen=(str = get_var(LEVEL_SET, v_hist)) ? atoi(str) : 0;
  1044. debug  =(get_var(LEVEL_SET, v_debug)  !=NULL);
  1045. Verbose=(get_var(LEVEL_SET, v_verbose)!=NULL);
  1046. if (S_histlen < 2) S_histlen=2;
  1047.  
  1048. if ( (str=get_var(LEVEL_SET,v_prompt)) ==NULL) str="$ ";
  1049. t=trueprompt;
  1050. while (*str)
  1051.     if (*str=='%' && Toupper(str[1])=='P') {
  1052.         str+=2;
  1053.         strcpy(t,get_var(LEVEL_SET,"_cwd"));
  1054.         t+=strlen(t);
  1055.         }
  1056.     else *t++=*str++;
  1057. strcpy(t,"\2330m");
  1058. }
  1059. SHAR_EOF
  1060. cat << \SHAR_EOF > shell.h
  1061.  
  1062. /*
  1063.  * SHELL.H
  1064.  *
  1065.  * (c)1986 Matthew Dillon     9 October 1986
  1066.  *
  1067.  *
  1068.  * SHELL include file.. contains shell parameters and extern's
  1069.  *
  1070.  * Version 2.07M by Steve Drew 10-Sep-87
  1071.  *
  1072.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  1073.  *
  1074.  */
  1075.  
  1076. #define RAW_CONSOLE 1   /* Set to 0 to compile out Cmd Line Editing */
  1077.  
  1078. #include <stdio.h>
  1079. #include <exec/exec.h>
  1080. #include <time.h>
  1081. #include <libraries/dos.h>
  1082. #include <libraries/dosextens.h>
  1083. #include <intuition/intuition.h>
  1084. #include <intuition/intuitionbase.h>
  1085. #include "shellfunctions.h"
  1086. #include <fcntl.h>
  1087. #include <libraries/arpbase.h>
  1088. #include <arpfunctions.h>
  1089.  
  1090. typedef struct FileInfoBlock FIB;
  1091.  
  1092. #define bmov movmem
  1093.  
  1094. #define MAXAV        256        /* Max. # arguments        */
  1095. #define MAXSRC        5        /* Max. # of source file levels */
  1096. #define MAXIF        10        /* Max. # of if levels        */
  1097. #define MAXALIAS    20        /* Max. # of alias levels    */
  1098. #define MAXMYFILES    9        /* Max. # of internal files    */
  1099.  
  1100. #define LEVEL_SET    0        /* which variable list to use   */
  1101. #define LEVEL_ALIAS    1
  1102. #define LEVEL_LABEL    2
  1103.  
  1104.     /* EXECOM.C defines */
  1105.  
  1106. #define FL_DOLLAR    0x01  /* One of the following */
  1107. #define FL_BANG        0x02
  1108. #define FL_PERCENT    0x04
  1109. #define FL_QUOTE    0x08
  1110. #define FL_IDOLLAR    0x10  /* Any or all of the following may be set */
  1111. #define FL_EOC        0x20
  1112. #define FL_EOL        0x40
  1113. #define FL_OVERIDE    0x80
  1114. #define FL_WILD        0x100
  1115. #define FL_MASK        (FL_DOLLAR|FL_BANG|FL_PERCENT|FL_QUOTE)
  1116.  
  1117. #ifndef NULL
  1118. #define NULL 0L
  1119. #endif
  1120.  
  1121. #define CHECKBREAK() dobreak()
  1122.  
  1123. #ifndef AZTEC_C
  1124. struct _dev {
  1125.     long  fd;
  1126.     short mode;
  1127.     };
  1128. #endif
  1129.  
  1130. struct HIST {
  1131.     struct HIST *next, *prev;    /* doubly linked list */
  1132.     char *line;            /* line in history    */
  1133. };
  1134.  
  1135. struct PERROR {
  1136.     int errnum;            /* Format of global error lookup */
  1137.     char *errstr;
  1138. };
  1139.  
  1140. struct DPTR {                /* Format of directory fetch pointer */
  1141.     BPTR lock;            /* lock on directory   */
  1142.     FIB *fib;            /* mod'd fib for entry */
  1143.     };
  1144.  
  1145. extern struct HIST *H_head, *H_tail;
  1146. extern struct PERROR Perror[];
  1147. extern struct DPTR *dopen();
  1148. extern char *set_var(), *get_var(), *next_word();
  1149. extern char *get_history(), *compile_av(), *get_pwd();
  1150. extern char *malloc(), *strcpy(), *strcat(), *index();
  1151. extern char **expand();
  1152. extern char *av[];
  1153. extern char *Current;
  1154. extern int  H_len, H_tail_base, H_stack;
  1155. extern int  E_stack;
  1156. extern int  Src_stack, If_stack, forward_goto;
  1157. extern int  ac;
  1158. extern int  debug, Rval, Verbose, disable, Quit;
  1159. extern int  Lastresult;
  1160. extern int  Exec_abortline;
  1161. extern int   S_histlen;
  1162. extern unsigned int options;
  1163. extern long  Cin, Cout, Cout_append;
  1164. extern char *Cin_name, *Cout_name;
  1165. extern char  Cin_type,  Cout_type;  /* these variables are in transition */
  1166. extern char *Pipe1, *Pipe2;
  1167.  
  1168. extern long Errno;
  1169. extern long Src_base[MAXSRC];
  1170. extern long Src_pos[MAXSRC];
  1171. extern char If_base[MAXIF];
  1172. extern struct Process *Myprocess;
  1173. extern struct CommandLineInterface *Mycli;
  1174.  
  1175. extern long atol(), Atol(), myatol();
  1176. SHAR_EOF
  1177. cat << \SHAR_EOF > shellfunctions.h
  1178. typedef    long    cList;
  1179. extern int Enable_Abort;
  1180.  
  1181. long                    AbleICR();
  1182. long                    AbortIO();
  1183. long                    ActivateGadget();
  1184. void                    ActivateWindow();
  1185. void                    AddAnimOb();
  1186. void                    AddBob();
  1187. void                    AddConfigDev();
  1188. void                    AddDevice();
  1189. long                    AddDosNode();
  1190. void                    AddFont();
  1191. void                    AddFreeList();
  1192. short                    AddGadget();
  1193. unsigned short                AddGList();
  1194. void                    AddHead();
  1195. struct Interrupt *            AddICRVector();
  1196. void                    AddIntServer();
  1197. void                    AddLibrary();
  1198. long                    AddMemList();
  1199. void                    AddPort();
  1200. void                    AddResource();
  1201. void                    AddSemaphore();
  1202. void                    AddTail();
  1203. void                    AddTask();
  1204. void                    AddTime();
  1205. void                    AddVSprite();
  1206. long                    Alert();
  1207. void *                    AllocAbs();
  1208. long                    AllocBoardMem();
  1209. cList                    AllocCList();
  1210. struct ConfigDev *            AllocConfigDev();
  1211. struct MemList *            AllocEntry();
  1212. unsigned long                AllocExpansionMem();
  1213. void *                    AllocMem();
  1214. long                    AllocPotBits();
  1215. void *                    AllocRaster();
  1216. char *                    AllocRemember();
  1217. long                    AllocSignal();
  1218. long                    AllocTrap();
  1219. struct WBObject *            AllocWBObject();
  1220. void *                    Allocate();
  1221. void                    AlohaWorkbench();
  1222. void                    AndRectRegion();
  1223. long                    AndRegionRegion();
  1224. void                    Animate();
  1225. short                    AreaDraw();
  1226. long                    AreaEllipse();
  1227. void                    AreaEnd();
  1228. short                    AreaMove();
  1229. void                    AskFont();
  1230. long                    AskSoftStyle();
  1231. long                    AttemptLockLayerRom();
  1232. long                    AttemptSemaphore();
  1233. short                    AutoRequest();
  1234. long                    AvailFonts();
  1235. long                    AvailMem();
  1236. void                    BeginIO();
  1237. void                    BeginRefresh();
  1238. void                    BeginUpdate();
  1239. void                    BeginLayer();
  1240. long                    BltBitMap();
  1241. long                    BltBitMapRastPort();
  1242. void                    BltClear();
  1243. void                    BltMaskBitMapRastPort();
  1244. void                    BltPattern();
  1245. void                    BltTemplate();
  1246. struct Window *                BuildSysRequest();
  1247. char *                    BumpRevision();
  1248. void                    Cause();
  1249. void                    CBump();
  1250. struct Events *                CDInputHandler();
  1251. void                    ChangeSprite();
  1252. struct IORequest *            CheckIO();
  1253. short                    ClearDMRequest();
  1254. void                    ClearEOL();
  1255. void                    ClearMenuStrip();
  1256. void                    ClearPointer();
  1257. void                    ClearRegion();
  1258. long                    ClearRectRegion();
  1259. void                    ClearScreen();
  1260. void                    ClipBit();
  1261. void                    Close();
  1262. void                    CloseDevice();
  1263. void                    CloseFont();
  1264. void                    CloseLibrary();
  1265. void                    CloseScreen();
  1266. void                    CloseWindow();
  1267. short                    CloseWorkBench();
  1268. void                    CMove();
  1269. short                    CmpTime();
  1270. long                    ConcatCList();
  1271. long                    ConfigBoard();
  1272. long                    ConfigChain();
  1273. long                    ConsoleDevice();
  1274. long                    CopperListInit();
  1275. cList                    CopyCList();
  1276. void                    CopyMem();
  1277. void                    CopyMemQuick();
  1278. void                    CopySBitMap();
  1279. struct Layer *                CreateBehindLayer();
  1280. BPTR        CreateDir();
  1281. struct MsgPort *            CreatePort();
  1282. struct Process *            CreateProc();
  1283. struct IOStdReq *            CreateStdIO();
  1284. struct Task *                CreateTask();
  1285. struct Layer *                CreateUpfrontLayer();
  1286. BPTR                    CurrentDir();
  1287. void                    CurrentTime();
  1288. void                    CWait();
  1289. long *                    DateStamp();
  1290. void                    Deallocate();
  1291. void                    Debug();
  1292. void                    Delay();
  1293. short                    DeleteFile();
  1294. void                    DeleteLayer();
  1295. void                    DeletePort();
  1296. void                    DeleteStdIO();
  1297. void                    DeleteTask();
  1298. struct Process *            DeviceProc();
  1299. void                    Disable();
  1300. void                    DisownBlitter();
  1301. short                    DisplayAlert();
  1302. void                    DisplayBeep();
  1303. void                    DisposeRegion();
  1304. void                    DoCollision();
  1305. long                    DoIO();
  1306. short                    DoubleClick();
  1307. void                    Draw();
  1308. void                    DrawBorder();
  1309. void                    DrawEllipse();
  1310. void                    DrawGList();
  1311. void                    DrawImage();
  1312. BPTR                    DupLock();
  1313. void                    Enable();
  1314. void                    EndRefresh();
  1315. void                    EndRequest();
  1316. void                    EndUpdate();
  1317. void                    Enqueue();
  1318. short                    ExNext();
  1319. short                    Examine();
  1320. short                    Execute();
  1321. void                    Exit();
  1322. struct ConfigDev *            FindConfigDev();
  1323. struct Node *                FindName();
  1324. struct MsgPort *            FindPort();
  1325. struct Resident *            FindResident();
  1326. struct SignalSemaphore *        FindSemaphore();
  1327. struct Task *                FindTask();
  1328. char *                    FindToolType();
  1329. short                    Flood();
  1330. void                    FlushCList();
  1331. void                    Forbid();
  1332. void                    FreeBoardMem();
  1333. void                    FreeCList();
  1334. void                    FreeColorMap();
  1335. void                    FreeConfigDev();
  1336. void                    FreeCopList();
  1337. void                    FreeCprList();
  1338. void                    FreeDiskObject();
  1339. void                    FreeEntry();
  1340. void                    FreeExpansionMem();
  1341. void                    FreeFreeList();
  1342. void                    FreeGBuffers();
  1343. void                    FreeMem();
  1344. void                    FreePotBits();
  1345. void                    FreeRaster();
  1346. void                    FreeRemember();
  1347. void                    FreeSignal();
  1348. void                    FreeSprite();
  1349. void                    FreeSysRequest();
  1350. void                    FreeTrap();
  1351. void                    FreeVPortCopLists();
  1352. void                    FreeWBObject();
  1353. long                    GetCC();
  1354. long                    GetCLBuf();
  1355. short                    GetCLChar();
  1356. short                    GetCLWord();
  1357. struct ColorMap *            GetColorMap();
  1358. long                    GetCurrentBinding();
  1359. struct Preferences *            GetDefPrefs();
  1360. struct DiskObject *            GetDiskObject();
  1361. short                    GetGBuffers();
  1362. long                    GetIcon();
  1363. struct Message *            GetMsg();
  1364. struct Preferences *            GetPrefs();
  1365. short                    GetRGB4();
  1366. long                    GetScreenData();
  1367. short                    GetSprite();
  1368. struct WBObject *            GetWBObject();
  1369. long                    IncrCLMark();
  1370. short                    Info();
  1371. void                    InitArea();
  1372. void                    InitBitMap();
  1373. long                    InitCLPool();
  1374. void                    InitCode();
  1375. void                    InitGMasks();
  1376. void                    InitGels();
  1377. void                    InitMasks();
  1378. void                    InitRastPort();
  1379. void                    InitRequester();
  1380. void                    InitResident();
  1381. void                    InitSemaphore();
  1382. void                    InitStruct();
  1383. void                    InitTmpRas();
  1384. void                    InitVPort();
  1385. void                    InitView();
  1386. BPTR                    Input();
  1387. void                    Insert();
  1388. struct Region *                InstallClipRegion();
  1389. long                    IntuiTextLength();
  1390. struct InputEvent *            Intuition();
  1391. long                    IoErr();
  1392. short                    IsInteractive();
  1393. struct MenuItem *            ItemAddress();
  1394. void                    LoadRGB4();
  1395. struct Segment *            LoadSeg();
  1396. void                    LoadView();
  1397. BPTR                    Lock();
  1398. void                    LockLayer();
  1399. void                    LockLayerInfo();
  1400. void                    LockLayerRom();
  1401. void                    LockLayers();
  1402. struct DeviceNode *            MakeDosNode();
  1403. long                    MakeFunctions();
  1404. struct Library *            MakeLibrary();
  1405. void                    MakeScreen();
  1406. void                    MakeVPort();
  1407. long                    MarkCList();
  1408. long                    MatchToolValue();
  1409. void                    ModifyIDCMP();
  1410. void                    ModifyProp();
  1411. void                    Move();
  1412. long                    MoveLayer();
  1413. void                    MoveScreen();
  1414. void                    MoveSprite();
  1415. void                    MoveWindow();
  1416. void                    MrgCop();
  1417. void                    NewList();
  1418. void                    NewModifyProp();
  1419. struct Region *                NewRegion();
  1420. void                    ObtainConfigBinding();
  1421. void                    ObtainSemaphore();
  1422. void                    ObtainSemaphoreList();
  1423. void                    OffGadget();
  1424. void                    OffMenu();
  1425. void                    OnGadget();
  1426. void                    OnMenu();
  1427. BPTR                    Open();
  1428. long                    OpenDevice();
  1429. struct Font *                OpenDiskFont();
  1430. struct Font *                OpenFont();
  1431. void                    OpenIntuition();
  1432. struct Library *            OpenLibrary();
  1433. struct MiscResource *            OpenResource();
  1434. struct Screen *                OpenScreen();
  1435. struct Window *                OpenWindow();
  1436. short                    OpenWorkBench();
  1437. void                    OrRectRegion();
  1438. long                    OrRegionRegion();
  1439. BPTR                    Output();
  1440. void                    OwnBlitter();
  1441. BPTR                    ParentDir();
  1442. short                    PeekCLMark();
  1443. void                    Permit();
  1444. void                    PolyDraw();
  1445. void                    PrintIText();
  1446. long                    PutCLBuf();
  1447. long                    PutCLChar();
  1448. long                    PutCLWord();
  1449. short                    PutDiskObject();
  1450. long                    PutIcon();
  1451. void                    PutMsg();
  1452. long                    PutWBObject();
  1453. void                    QBSBlit();
  1454. void                    QBlit();
  1455. short                    RawKeyConvert();
  1456. long                    Read();
  1457. char                    ReadExpansionByte();
  1458. long                    ReadExpansionRom();
  1459. short                    ReadPixel();
  1460. void                    RectFill();
  1461. void                    RefreshGadgets();
  1462. void                    RefreshGList();
  1463. void                    RefreshWindowFrame();
  1464. void                    ReleaseConfigBinding();
  1465. void                    ReleaseSemaphore();
  1466. void                    ReleaseSemaphoreList();
  1467. void                    RemConfigDev();
  1468. long                    RemDevice();
  1469. void                    RemFont();
  1470. struct Node *                RemHead();
  1471. void                    RemIBob();
  1472. void                    RemICRVector();
  1473. void                    RemIntServer();
  1474. long                    RemLibrary();
  1475. unsigned short                RemoveGList();
  1476. void                    RemPort();
  1477. void                    RemResource();
  1478. void                    RemSemaphore();
  1479. struct Node *                RemTail();
  1480. void                    RemTask();
  1481. void                    RemVSprite();
  1482. void                    RemakeDisplay();
  1483. void                    Remove();
  1484. unsigned short                RemoveGadget();
  1485. short                    Rename();
  1486. void                    ReplyMsg();
  1487. void                    ReportMouse();
  1488. short                    Request();
  1489. void                    RethinkDisplay();
  1490. void                    ScreenToBack();
  1491. void                    ScreenToFront();
  1492. void                    ScrollLayer();
  1493. void                    ScrollRaster();
  1494. void                    ScrollVPort();
  1495. long                    Seek();
  1496. void                    SendIO();
  1497. void                    SetAPen();
  1498. void                    SetBPen();
  1499. void                    SetCollision();
  1500. short                    SetComment();
  1501. void                    SetCurrentBinding();
  1502. short                    SetDMRequest();
  1503. void                    SetDRMd();
  1504. long                    SetExcept();
  1505. long                    SetFont();
  1506. long                    SetFunction();
  1507. long                    SetICR();
  1508. struct Interrupt *            SetIntVector();
  1509. short                    SetMenuStrip();
  1510. void                    SetPointer();
  1511. struct Preferences *            SetPrefs();
  1512. short                    SetProtection();
  1513. void                    SetRast();
  1514. void                    SetRGB4();
  1515. void                    SetRGB4CM();
  1516. long                    SetSR();
  1517. long                    SetSignal();
  1518. long                    SetSoftStyle();
  1519. short                    SetTaskPri();
  1520. void                    SetWindowTitles();
  1521. void                    ShowTitle();
  1522. void                    Signal();
  1523. long                    SizeCList();
  1524. short                    SizeLayer();
  1525. void                    SizeWindow();
  1526. void                    SortGList();
  1527. cList                    SplitCList();
  1528. cList                    SubCList();
  1529. void                    SubTime();
  1530. void                    SubLibrary();
  1531. void                    SumKickData();
  1532. long                    SuperState();
  1533. void                    SwapBitsRastPortClipRect();
  1534. void                    SyncSBitMap();
  1535. long                    Text();
  1536. long                    TextLength();
  1537. long                    Translate();
  1538. long                    UnGetCLChar();
  1539. long                    UnGetCLWord();
  1540. void                    UnLoadSeg();
  1541. void                    UnLock();
  1542. short                    UnPutCLChar();
  1543. short                    UnPutCLWord();
  1544. void                    UnlockLayer();
  1545. void                    UnlockLayerInfo();
  1546. void                    UnlockLayerRom();
  1547. void                    UnlockLayers();
  1548. short                    UpfrontLayer();
  1549. void                    UserState();
  1550. short                    VBeamPos();
  1551. struct View *                ViewAddress();
  1552. struct ViewPort *            ViewPortAddress();
  1553. short                    WBenchToBack();
  1554. short                    WBenchToFront();
  1555. long                    Wait();
  1556. void                    WaitBOVP();
  1557. void                    WaitBlit();
  1558. short                    WaitForChar();
  1559. long                    WaitIO();
  1560. struct Message *            WaitPort();
  1561. void                    WaitTOF();
  1562. struct Layer *                WhichLayer();
  1563. short                    WindowLimits();
  1564. void                    WindowToBack();
  1565. void                    WindowToFront();
  1566. long                    Write();
  1567. long                    WriteExpansionByte();
  1568. void                    WritePixel();
  1569. void                    WritePotgo();
  1570. void                    XorRectRegion();
  1571. long                    XorRegionRegion();
  1572. SHAR_EOF
  1573. cat << \SHAR_EOF > sub.c
  1574.  
  1575. /*
  1576.  * SUB.C
  1577.  *
  1578.  * (c)1986 Matthew Dillon     9 October 1986
  1579.  *
  1580.  * Version 2.07M by Steve Drew 10-Sep-87
  1581.  *
  1582.  * Version 3.01A by Carlo Borreo & Cesare Dieni 17-Nov-88
  1583.  *
  1584.  */
  1585.  
  1586. extern char *v_lasterr, *v_stat;
  1587.  
  1588. #define HM_STR 0              /* various HISTORY retrieval modes */
  1589. #define HM_REL 1
  1590. #define HM_ABS 2
  1591.  
  1592. /* extern BPTR Clock; */
  1593.  
  1594. seterr()
  1595. {
  1596. char buf[32];
  1597. int stat;
  1598.  
  1599. sprintf(buf, "%d", Lastresult);
  1600. set_var(LEVEL_SET, v_lasterr, buf);
  1601. stat = atoi(get_var(LEVEL_SET, v_stat));
  1602. if (stat < Lastresult) stat = Lastresult;
  1603. sprintf(buf, "%d", stat);
  1604. set_var(LEVEL_SET, v_stat, buf);
  1605. }
  1606.  
  1607.  
  1608. char *
  1609. next_word(str)
  1610. register char *str;
  1611. {
  1612.    while (*str  &&  *str != ' '  &&  *str != 9 && (unsigned char)*str != 0xA0)
  1613.       ++str;
  1614.    while (*str  && (*str == ' ' || *str == 9 || (unsigned char)*str == 0xA0))
  1615.       ++str;
  1616.    return (str);
  1617. }
  1618.  
  1619. char *
  1620. compile_av(av, start, end, delim)
  1621. char **av;
  1622. unsigned char delim;
  1623. {
  1624. char *cstr;
  1625. int len;
  1626. register unsigned int i;
  1627.  
  1628. len = 0;
  1629. for (i = start; i < end; ++i) len += strlen(av[i]) + 1;
  1630. cstr = malloc(len + 1);
  1631. *cstr = '\0';
  1632. for (i = start; i < end; ++i) {
  1633.     if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
  1634.     strcat (cstr, av[i]);
  1635.     if (i + 1 < end) strncat(cstr, &delim, 1);
  1636.     }
  1637. return (cstr);
  1638. }
  1639.  
  1640.  
  1641. /*
  1642.  * FREE(ptr)   --frees without actually freeing, so the data is still good
  1643.  *               immediately after the free.
  1644.  */
  1645.  
  1646.  
  1647. Free(ptr)
  1648. char *ptr;
  1649. {
  1650.    static char *old_ptr;
  1651.  
  1652.    if (old_ptr)
  1653.       free (old_ptr);
  1654.    old_ptr = ptr;
  1655. }
  1656.  
  1657. /*
  1658.  * Add new string to history (H_head, H_tail, H_len,
  1659.  *  S_histlen
  1660.  */
  1661.  
  1662. add_history(str)
  1663. char *str;
  1664. {
  1665.    register struct HIST *hist;
  1666.  
  1667.    if (H_head != NULL && strcmp(H_head->line, str) == 0)
  1668.        return(0);
  1669.    while (H_len > S_histlen)
  1670.       del_history();
  1671.    hist = (struct HIST *)malloc (sizeof(struct HIST));
  1672.    if (H_head == NULL) {
  1673.       H_head = H_tail = hist;
  1674.       hist->next = NULL;
  1675.    } else {
  1676.       hist->next = H_head;
  1677.       H_head->prev = hist;
  1678.       H_head = hist;
  1679.    }
  1680.    hist->prev = NULL;
  1681.    hist->line = malloc (strlen(str) + 1);
  1682.    strcpy (hist->line, str);
  1683.    ++H_len;
  1684. }
  1685.  
  1686. del_history()
  1687. {
  1688.    if (H_tail) {
  1689.       --H_len;
  1690.       ++H_tail_base;
  1691.       free (H_tail->line);
  1692.       if (H_tail->prev) {
  1693.          H_tail = H_tail->prev;
  1694.          free (H_tail->next);
  1695.          H_tail->next = NULL;
  1696.       } else {
  1697.          free (H_tail);
  1698.          H_tail = H_head = NULL;
  1699.       }
  1700.    }
  1701. }
  1702.  
  1703. char *
  1704. get_history(ptr)
  1705. char *ptr;
  1706. {
  1707.    register struct HIST *hist;
  1708.    register int len;
  1709.    int mode = HM_REL;
  1710.    int num  = 1;
  1711.    char *str;
  1712.    char *result = NULL;
  1713.  
  1714.    if (ptr[1] >= '0' && ptr[1] <= '9') {
  1715.       mode = HM_ABS;
  1716.       num  = atoi(&ptr[1]);
  1717.       goto skip;
  1718.    }
  1719.    switch (ptr[1]) {
  1720.    case '!':
  1721.       break;
  1722.    case '-':
  1723.       num += atoi(&ptr[2]);
  1724.       break;
  1725.    default:
  1726.       mode = HM_STR;
  1727.       str  = ptr + 1;
  1728.       break;
  1729.    }
  1730. skip:
  1731.    switch (mode) {
  1732.    case HM_STR:
  1733.       len = strlen(str);
  1734.       for (hist = H_head; hist; hist = hist->next) {
  1735.          if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
  1736.             result = hist->line;
  1737.             break;
  1738.          }
  1739.       }
  1740.       break;
  1741.    case HM_REL:
  1742.       for (hist = H_head; hist && num--; hist = hist->next);
  1743.       if (hist)
  1744.          result = hist->line;
  1745.       break;
  1746.    case HM_ABS:
  1747.       len = H_tail_base;
  1748.       for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
  1749.       if (hist)
  1750.          result = hist->line;
  1751.       break;
  1752.    }
  1753.    if (result) {
  1754.       fprintf(stderr,"%s\n",result);
  1755.       return(result);
  1756.    }
  1757.    printf("History failed\n");
  1758.    return ("");
  1759. }
  1760.  
  1761. replace_head(str)
  1762. char *str;
  1763. {
  1764.    if (str == NULL)
  1765.       str = "";
  1766.    if (H_head) {
  1767.       free (H_head->line);
  1768.       H_head->line = malloc (strlen(str)+1);
  1769.       strcpy (H_head->line, str);
  1770.    }
  1771. }
  1772.  
  1773.  
  1774. pError(str)
  1775. char *str;
  1776. {
  1777.    int ierr = (long)IoErr();
  1778.    ierror(str, ierr);
  1779. }
  1780.  
  1781. ierror(str, err)
  1782. register char *str;
  1783. {
  1784.    register struct PERROR *per = Perror;
  1785.  
  1786.    if (err) {
  1787.       for (; per->errstr; ++per) {
  1788.          if (per->errnum == err) {
  1789.             fprintf (stderr, "%s%s%s\n",
  1790.                   per->errstr,
  1791.                   (str) ? ": " : "",
  1792.                   (str) ? str : "");
  1793.             return ((short)err);
  1794.          }
  1795.       }
  1796.       fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
  1797.    }
  1798.    return ((short)err);
  1799. }
  1800.  
  1801. /*
  1802.  * Disk directory routines
  1803.  *
  1804.  * dptr = dopen(name, stat)
  1805.  *    struct DPTR *dptr;
  1806.  *    char *name;
  1807.  *    int *stat;
  1808.  *
  1809.  * dnext(dptr, name, stat)
  1810.  *    struct DPTR *dptr;
  1811.  *    char **name;
  1812.  *    int  *stat;
  1813.  *
  1814.  * dclose(dptr)                  -may be called with NULL without harm
  1815.  *
  1816.  * dopen() returns a struct DPTR, or NULL if the given file does not
  1817.  * exist.  stat will be set to 1 if the file is a directory.  If the
  1818.  * name is "", then the current directory is openned.
  1819.  *
  1820.  * dnext() returns 1 until there are no more entries.  The **name and
  1821.  * *stat are set.  *stat = 1 if the file is a directory.
  1822.  *
  1823.  * dclose() closes a directory channel.
  1824.  *
  1825.  */
  1826.  
  1827. struct DPTR *
  1828. dopen(name, stat)
  1829. char *name;
  1830. int *stat;
  1831. {
  1832.    struct DPTR *dp;
  1833.  
  1834.    *stat = 0;
  1835.    dp = (struct DPTR *)malloc(sizeof(struct DPTR));
  1836.    if (*name == '\0')
  1837.       dp->lock = DupLock(Myprocess->pr_CurrentDir);
  1838.    else
  1839.       dp->lock = Lock (name,ACCESS_READ);
  1840.    if (dp->lock == NULL) {
  1841.       free (dp);
  1842.       return (NULL);
  1843.    }
  1844.    dp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1845.    if (!Examine (dp->lock, dp->fib)) {
  1846.       pError (name);
  1847.       dclose (dp);
  1848.       return (NULL);
  1849.    }
  1850.    if (dp->fib->fib_DirEntryType >= 0)
  1851.       *stat = 1;
  1852.    return (dp);
  1853. }
  1854.  
  1855. dnext(dp, pname, stat)
  1856. struct DPTR *dp;
  1857. char **pname;
  1858. int *stat;
  1859. {
  1860.    if (dp == NULL)
  1861.       return (0);
  1862.    if (ExNext (dp->lock, dp->fib)) {
  1863.       *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
  1864.       *pname = dp->fib->fib_FileName;
  1865.       return (1);
  1866.    }
  1867.    return (0);
  1868. }
  1869.  
  1870.  
  1871. dclose(dp)
  1872. struct DPTR *dp;
  1873. {
  1874.    if (dp == NULL)
  1875.       return (1);
  1876.    if (dp->fib)
  1877.       FreeMem (dp->fib,(long)sizeof(*dp->fib));
  1878.    if (dp->lock)
  1879.       UnLock (dp->lock);
  1880.    free (dp);
  1881.    return (1);
  1882. }
  1883.  
  1884.  
  1885. isdir(file)
  1886. char *file;
  1887. {
  1888.    register struct DPTR *dp;
  1889.    int stat;
  1890.  
  1891.    stat = 0;
  1892.    if (dp = dopen (file, &stat))
  1893.       dclose(dp);
  1894.    return (stat == 1);
  1895. }
  1896.  
  1897.  
  1898. free_expand(av)
  1899. register char **av;
  1900. {
  1901.    char **base = av;
  1902.  
  1903.    if (av) {
  1904.       while (*av) {
  1905.          free (*av);
  1906.          ++av;
  1907.       }
  1908.       free (base);
  1909.    }
  1910. }
  1911.  
  1912. /*
  1913.  * EXPAND(base,pac)
  1914.  *    base           - char * (example: "df0:*.c")
  1915.  *    pac            - int  *  will be set to # of arguments.
  1916.  *
  1917.  * 22-May-87 SJD.  Heavily modified to allow recursive wild carding and
  1918.  *                 simple directory/file lookups. Returns a pointer to
  1919.  *                 an array of pointers that contains the full file spec
  1920.  *                 eg. 'df0:c/sear*' would result in : 'df0:C/Search'
  1921.  *
  1922.  *                 Now no longer necessary to Examine the files a second time
  1923.  *                 in do_dir since expand will return the full file info
  1924.  *                 appended to the file name. Set by formatfile().
  1925.  *                 eg. fullfilename'\0'rwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS
  1926.  *
  1927.  *                 Caller must call free_expand when done with the array.
  1928.  *
  1929.  * base             bname =       ename =
  1930.  * ------           -------       -------
  1931.  *  "*"               ""            "*"
  1932.  *  "!*.info"         ""            "*.info" (wild_exclude set)
  1933.  *  "su*d/*"          ""            "*"      (tail set)
  1934.  *  "file.*"          ""            "file.*"
  1935.  *  "df0:c/*"         "df0:c"       "*"
  1936.  *  ""                ""            "*"
  1937.  *  "df0:.../*"       "df0:"        "*"      (recur set)
  1938.  *  "df0:sub/.../*"   "df0:sub"     "*"      (recur set)
  1939.  *
  1940.  * ---the above base would be provided by execom.c or do_dir().
  1941.  * ---the below base would only be called from do_dir().
  1942.  *
  1943.  *  "file.c"          "file.c"      ""       if (dp == 0) fail else get file.c
  1944.  *  "df0:"            "df0:"        "*"
  1945.  *  "file/file"       "file/file"   ""       (dp == 0) so fail
  1946.  *  "df0:.../"        "df0:"        "*"      (recur set)
  1947.  *
  1948.  */
  1949.  
  1950.  
  1951. char **
  1952. expand(base, pac)
  1953. char *base;
  1954. int *pac;
  1955. {
  1956.    register char *ptr;
  1957.    char **eav = (char **)malloc(sizeof(char *) * (2));
  1958.    short eleft, eac;
  1959.    char *name;
  1960.    char *svfile();
  1961.    char *bname, *ename, *tail;
  1962.    int stat, recur, scr, bl;
  1963.    register struct DPTR *dp;
  1964.  
  1965.    *pac = recur = eleft = eac = 0;
  1966.  
  1967.    base = strcpy(malloc(strlen(base)+1), base);
  1968.    for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
  1969.  
  1970.    if (!*ptr)   /* no wild cards */
  1971.       --ptr;
  1972.    else
  1973.       for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
  1974.  
  1975.    if (ptr < base) {
  1976.       bname = strcpy (malloc(1), "");
  1977.    } else {
  1978.       scr = ptr[1];
  1979.       ptr[1] = '\0';
  1980.       if (!strcmp(ptr-3,".../")) {
  1981.          recur = 1;
  1982.          *(ptr-3) = '\0';
  1983.       }
  1984.       bname = strcpy (malloc(strlen(base)+2), base);
  1985.       ptr[1] = scr;
  1986.    }
  1987.    bl = strlen(bname);
  1988.    ename = ++ptr;
  1989.    for (; *ptr && *ptr != '/'; ++ptr);
  1990.    scr = *ptr;
  1991.    *ptr = '\0';
  1992.    if (scr) ++ptr;
  1993.    tail = ptr;
  1994.  
  1995.    if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
  1996.       free (bname);
  1997.       free (base);
  1998.       free (eav);
  1999.       return (NULL);
  2000.    }
  2001.  
  2002.    if (!stat) {                /* eg. 'dir file' */
  2003.       char *p,*s;
  2004.       for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
  2005.       if (s != bname) ++s;
  2006.       *s ='\0';
  2007.       eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
  2008.       goto done;
  2009.    }
  2010.    if (!*ename) ename = "*";    /* eg. dir df0: */
  2011.    if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
  2012.       bname[bl] = '/';
  2013.       bname[++bl] = '\0';
  2014.    }
  2015.    while ((dnext (dp, &name, &stat)) && !breakcheck()) {
  2016.         int match = compare_ok(ename,name);
  2017.       if (match && !(!recur && *tail)) {
  2018.          if (eleft < 2) {
  2019.                char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  2020.                movmem (eav, scrav, (eac + 1) << 2);
  2021.                free (eav);
  2022.                eav = scrav;
  2023.                eleft = 10;
  2024.          }
  2025.          eav[eac++] = svfile(bname,name,dp->fib);
  2026.          --eleft;
  2027.       }
  2028.       if ((*tail && match) || recur) {
  2029.          int alt_ac;
  2030.          char *search, **alt_av, **scrav;
  2031.          BPTR lock;
  2032.  
  2033.          if (!stat)           /* expect more dirs, but this not a dir */
  2034.             continue;
  2035.          lock = CurrentDir (dp->lock);
  2036.          search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
  2037.          strcpy (search, name);
  2038.          strcat (search, "/");
  2039.          if (recur) {
  2040.             strcat(search, ".../");
  2041.             strcat(search, ename);
  2042.          }
  2043.          strcat (search, tail);
  2044.          scrav = alt_av = expand (search, &alt_ac);
  2045.          /* free(search); */
  2046.          CurrentDir (lock);
  2047.          if (scrav) {
  2048.             while (*scrav) {
  2049.                int l;
  2050.                if (eleft < 2) {
  2051.                   char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  2052.                   movmem (eav, scrav, (eac + 1) << 2);
  2053.                   free (eav);
  2054.                   eav = scrav;
  2055.                   eleft = 10;
  2056.                }
  2057.  
  2058.                l = strlen(*scrav);
  2059.                scrav[0][l] = ' ';
  2060.                eav[eac] = malloc(bl+l+45);
  2061.                strcpy(eav[eac], bname);
  2062.                strcat(eav[eac], *scrav);
  2063.                eav[eac][l+bl] = '\0';
  2064.  
  2065.                free (*scrav);
  2066.                ++scrav;
  2067.                --eleft, ++eac;
  2068.             }
  2069.             free (alt_av);
  2070.          }
  2071.       }
  2072.    }
  2073. done:
  2074.    dclose (dp);
  2075.    *pac = eac;
  2076.    eav[eac] = NULL;
  2077.    free (bname);
  2078.    free (base);
  2079.    if (eac) {
  2080.       return (eav);
  2081.    }
  2082.    free (eav);
  2083.    return (NULL);
  2084. }
  2085.  
  2086. /*
  2087.  * Compare a wild card name with a normal name
  2088.  */
  2089.  
  2090. #define MAXB   8
  2091.  
  2092. compare_ok(wild, name)
  2093. char *wild, *name;
  2094. {
  2095. register char *w = wild;
  2096. register char *n = name;
  2097. char *back0[MAXB], *back1[MAXB];
  2098. int bi=0, queryflag;
  2099.  
  2100. if (*w=='!') return !compare_ok(wild+1,name);
  2101. if (queryflag=(*w=='&')) w++;
  2102. while (*n || *w) {
  2103.    switch (*w) {
  2104.       case '*':
  2105.        if (bi==MAXB) { printf(stderr,"Too many levels of '*'\n"); return 0; }
  2106.        back0[bi] = w;
  2107.        back1[bi] = n;
  2108.        ++bi;
  2109.        ++w;
  2110.        continue;
  2111. goback:
  2112.        --bi;
  2113.        while (bi >= 0 && *back1[bi] == '\0') --bi;
  2114.        if (bi < 0) return 0;
  2115.        w = back0[bi] + 1;
  2116.        n = ++back1[bi];
  2117.        ++bi;
  2118.        continue;
  2119.       case '?':
  2120.        if (!*n) goto goback;
  2121.        break;
  2122.       default:
  2123.        if (Toupper(*n)!=Toupper(*w)) goto goback;
  2124.        break;
  2125.       }
  2126.    if (*n) ++n;
  2127.    if (*w) ++w;
  2128.    }
  2129. if (queryflag) {
  2130.     char in[256];
  2131.     printf("Select \23337m%-16s\2330m [y/n] ? ",name);
  2132.     gets(in);
  2133.     return (Toupper(*in)=='Y');
  2134.     }
  2135. return 1;
  2136. }
  2137.  
  2138. char *svfile(s1,s2,fib)
  2139. char *s1,*s2;
  2140. FIB *fib;
  2141. {
  2142. char *p = malloc (strlen(s1)+strlen(s2)+45);
  2143. strcpy(p, s1);
  2144. strcat(p, s2);
  2145. formatfile(p,fib);
  2146. return p;
  2147. }
  2148.  
  2149. /* will have either of these formats:
  2150.  *
  2151.  *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  2152.  *    fullfilename'\0'hsparwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  2153.  *                              1111111111222222222233333333334 4  4
  2154.  *                    01234567890123456789012345678901234567890 1  2
  2155.  */
  2156. formatfile(str,fib)
  2157. char *str;
  2158. FIB *fib;
  2159. {
  2160. char *dates();
  2161. int i;
  2162. while(*str++);
  2163. for (i=7; i>=0; i--)
  2164.     *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
  2165. if (fib->fib_DirEntryType < 0)
  2166.   sprintf(str,"  %6ld %4ld  ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
  2167. else strcpy(str,"   <Dir>       ");
  2168. strcat(str,dates(&fib->fib_Date));
  2169. }
  2170.  
  2171. /* Sort routines */
  2172.  
  2173. long cmp(s1, s2)
  2174. char **s1, **s2;
  2175. {
  2176. return (long)Strcmp(*s1, *s2);
  2177. }
  2178.  
  2179. Cmp() {
  2180. #asm
  2181.     public    _geta4
  2182.     movem.l    d2-d3/a4/a6,-(sp)
  2183.     movem.l    a0/a1,-(sp)
  2184.     bsr    _geta4
  2185.     bsr    _cmp
  2186.     addq.l    #8,sp
  2187.     movem.l    (sp)+,d2-d3/a4/a6
  2188. #endasm
  2189. }
  2190.  
  2191. QuickSort(av, n)
  2192. char *av[];
  2193. int n;
  2194. {
  2195. QSort(av, (long)n, 4L, Cmp);
  2196. }
  2197. SHAR_EOF
  2198. #    End of shell archive
  2199. exit 0
  2200. -- 
  2201. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2202. Have five nice days.
  2203.